﻿using RabbitMQ.Client;
using System.Text;
using RabbitMQ.Client.Events;
using System;
using MQTools;
using DAL;
using System.Collections;
using System.Collections.Generic;

namespace MQsender
{
    public  class Program
    {
        public static void Main(string[] args)
        {
            //Basic();
            //Fanout();
            //Direct();
            //Topic();
            //TestRabbitMQ();
            //Console.WriteLine(MinDicOrderStr("acbca"));
            //int rs = MaxDamage(4, 4, 2, new int[] { 4, 3, 2, 1 });
            //Console.WriteLine(rs);

            //int[] rs = GetChoosenNum(2, 3, new int[] { 1,2,3,4,5}, new int[] { 1,0,1,0,1});
            //foreach(var item in rs)
            //{
            //    Console.WriteLine(item);
            //}
            int m = 5,n=2;
            int [][]status = new int[m][];
            for (int i = 0; i < m; i++) status[i] = new int[2];


            Console.WriteLine(MaxSubMulti(new int[] { -8, -4, -2, -1, 0, 1, 2, 4, 8 }));
            //MaxMinQues(new int[] { 3, 5, 1 }, new int[][] { new int[] { 4, 3 }, new int[] { 3, 1 }, new int[] { 6, 5 } });
        }

 

        public  static int[] MaxSubMulti(int[] a)
        {
            int len = a.Length;
            int[][] dp = new int[len + 1][];
            
            for (int i = 0; i <= len; i++)
            {
                dp[i] = new int[len + 1];
               
            }
            for(int i = 0; i < len; i++)
            {
                dp[i + 1][i + 1] = a[i]; //数组只含一个成员乘积就是他本身*1
            }
            dp[0][0] = 1;
            int begin = 0, end = 0;
            int maxMulti = 1;
            for(int i = 1; i <= len; i++)
            {
                for(int j = 1; j<i ; j++)
                {
                    //dp[j][i] = Math.Max(dp[j][i] * dp[j-1][i- 1], dp[j][i]);
                    dp[j][i] = dp[i][i] * dp[j][i - 1];
                   
                    if (dp[j][i] >=dp[i][i]&& dp[j][i]>maxMulti)
                    {
                        begin = j;
                        end = i;
                        maxMulti = dp[j][i];
                        Console.WriteLine("长数组 {0},{1},{2}",begin,end,maxMulti);
                    }
                    else if (dp[j][i] < dp[i][i] && dp[i][i] > maxMulti)
                    {
                        maxMulti = dp[i][i];
                        begin = i;
                        end = i;
                        Console.WriteLine("单数组{0},{1},{2}", begin, end,maxMulti);
                    }
                }
            }
      
            int[] rs = new int[end - begin + 1];
            for(int i = 0; i < rs.Length; i++)
            {
                rs[i] = begin+i-1;
                Console.WriteLine(rs[i]);
            }
            return rs;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="m">m个居民</param>
        /// <param name="n">n个商场</param>
        /// <returns></returns>
        public static int[] GetChoosenNum(int m,int n,int []loc,int[] identity)
        {
            //已经知道位置是按照升序排列，那么直接双指针做
            int[] rs = new int[n];
            var len = m + n;

            //先哈希记录一下商场对应第几个
            IDictionary<int, int> map = new Dictionary<int, int>();
            int mall_index = 0;
            for(int i = 0; i < len; i++)
            {
                if (identity[i]==1)
                map.TryAdd(loc[i], mall_index++);
            }
            //中心扩散双指针解决
            for(int i = 0; i < len; i++)
            {
                if (identity[i] == 0)//若为居民
                {
                    int l = i - 1, r = i + 1;
                    int user_loc = loc[i];
                    int left_dist = int.MaxValue, right_dist = int.MaxValue;
                    while (l >= 0)
                    {
                        if (identity[l] == 1)
                        {
                            left_dist = Math.Abs(user_loc - loc[l]);
                            break;
                        };
                        l--;
                    }
                    while (r < len)
                    {
                        if (identity[r] == 1)
                        {
                            right_dist = Math.Abs(user_loc - loc[r]);
                            break;
                        };
                        r++;
                    }
                    if (left_dist <= right_dist)
                    {
                        rs[map[loc[l]]]++;
                        //Console.WriteLine("用户在{0},{1}，{2}选左边 {3},{4}", user_loc, left_dist, right_dist, map[loc[l]], map[loc[r]]);
                    }
                    else
                    {
                        rs[map[loc[r]]]++;
                        //Console.WriteLine("用户在{0},{1}，{2}选右边", user_loc, left_dist, right_dist);

                    }
                }
             }


            return rs;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="n">技能数量</param>
        /// <param name="m">回合数</param>
        /// <param name="k">一个技能最多丢几次</param>
        /// <returns></returns>
        public static int MaxDamage(int n ,int m,int k,int[] actionDamage)
        {
            int maxDamage = 0;
            //直接存hashmap  存的是技能伤害和对应使用次数
            IDictionary<int, int> dic = new Dictionary<int, int>();
            Array.Sort(actionDamage,(a,b)=>b-a);//先对招式降序排序
            foreach (var d in actionDamage)
            {
                dic.TryAdd(d, 0);
            }
            while (m-- > 0)
            {
                bool findTarget = false;
                //遍历哈希找不在CD的技能
                foreach (var action in dic.Keys)
                {
                    //没处在冷却中，直接用，次数+1
                    if (findTarget==false&&dic[action] < k)
                    {
                        dic[action]++;
                        Console.WriteLine(action);
                        findTarget = true;
                        maxDamage += action;
                    }
                    //冷却中，次数-1，下一个
                    else if(findTarget==false && dic[action] == k)
                    {
                        dic[action]--;
                    }
                    //如果已经找到了，给下一个状态恢复一下次数，不用继续往后了
                    else if(findTarget==true)
                    {
                        dic[action] = Math.Max(dic[action] - 1, 0);
                        break;
                    }
                }
            }
           
            return maxDamage;
        }
        public static int MaxMinQues(int[] header, int[][]prices)
        {
            int N = header[0];//总共N件货物
            int X = header[1];//X现金
            int Y = header[2];//总共Y张券
            IDictionary<int, int> dic = new Dictionary<int, int>(); 
       
            int[][][] dp = new int[N + 1][][];
            for(int i = 0; i < dp.Length; i++)
            {
                dp[i] = new int[X+1][];
                for(int j = 0;j< dp[i].Length; j++)
                {
                    dp[i][j] = new int[Y+1];
                }
            }
            int reachable_maxNum = 0;
            dp[0][X][Y] =0;
            for(int i = 1; i <= N; i++)
            {
                int curPrice = prices[i-1][0];
                int decPrice = prices[i-1][1];
                Console.WriteLine("第" + i + "轮");
                for(int j = 0; j < i; j++)
                {
                    if (curPrice <=X)
                        for (int f = Y; f >= 0; f--)
                            for (int k = X; k >= curPrice; k--){
                                if (dp[j][k][f] !=i-1) continue;
                                    dp[j + 1][k - curPrice][f] = i;
                                Console.WriteLine("{0},{1},{2}   不用券买，{3}，{4},{5}",j,k,f, j + 1, k - curPrice, f);
                                if (j + 1 >= reachable_maxNum){
                                    reachable_maxNum = j + 1;
                                    if (!dic.ContainsKey(reachable_maxNum)) dic.TryAdd(reachable_maxNum, k - curPrice);
                                    else dic[reachable_maxNum] = Math.Max(dic[reachable_maxNum], k - curPrice);
                                }
                            }
                    if (decPrice <= X){
                        for (int f = Y; f > 0; f--){
                            for (int k = X; k >= decPrice; k--){
                                if (dp[j][k][f] != i-1) continue;
                                dp[j + 1][k - decPrice][f - 1] = i;
                                Console.WriteLine("{0},{1},{2}  用券买，{3}，{4},{5}", j, k, f,j + 1, k - decPrice, f - 1);
                                if (j + 1 >= reachable_maxNum){
                                    reachable_maxNum = j + 1;
                                    if (!dic.ContainsKey(reachable_maxNum)){
                                        dic.TryAdd(reachable_maxNum, k - decPrice);
                                    }
                                    else{
                                        dic[reachable_maxNum] = Math.Max(dic[reachable_maxNum], k - decPrice);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            Console.WriteLine(reachable_maxNum.ToString()+""+ (X-dic[reachable_maxNum]).ToString());
            return dic[reachable_maxNum];
        }




        public static string MinDicOrderStr(string seq)
        {
            
            int len = seq.Length;
            List<int> diff = new List<int>();
            char[] str = seq.ToCharArray();
            int[] couple = new int[len/2];
            int[] single = new int[len/2];
    
            if (len % 2 == 0)//偶数情况
            {
                int mid = len / 2-1;
                for(int i = 0; i <= mid;i++) {
                    var l = seq[i];
                    var r = seq[len - i - 1];
                    if (l != r) diff.Add(i);
                    couple[i]=(l-'a')+(r-'a');
                   
                    single[i]= Math.Abs(l - r);
                }
                if (diff.Count == 1)//只有一处不对称
                {
                    int target = diff[0];
                    str[target] = str[len-target-1] = 'a'; 
                }
                else if(diff.Count==2)//两处不对称 只能是两个single
                {
                    solu2(str,diff,len);
                }
                else//全对称 挑最大的一对改
                {
                    solu3(str,couple, diff, len);
                }
            }
            else//奇数情况
            {
                int mid = len / 2;
                for (int i = 0; i < mid; i++)
                {
                    var l = seq[i];
                    var r = seq[len - i - 1];
                    if (l != r) diff.Add(i);
                    couple[i] = (l - 'a') + (r - 'a');
                    single[i] = Math.Abs(l - r);
                }
                if (diff.Count == 1)//只有一处不对称
                {
                    int target = diff[0];
                    str[target] = str[len - target - 1] = 'a';
                    str[mid] = 'a';
                }
                else if (diff.Count == 2)//两处不对称 只能是两个single
                {
                    solu2(str, diff, len);
                }
                else//全对称 
                {
                    solu3(str, couple, diff, len);
                }
            }

            StringBuilder sb = new StringBuilder(); 
            foreach(var c in str)
            {
                sb.Append(c);
            }
            return sb.ToString() ;
        }
        public static void solu2(char[] str, List<int> diff, int len)
        {
            foreach (var target in diff)
            {
                if (str[target] - str[len - target - 1] >= 0)
                {
                    str[target] = str[len - target - 1];
                }
                else
                {
                    str[len - target - 1] = str[target];
                }
            }
        }
        public static void solu3(char[] str, int[] couple, List<int> diff, int len)
        {
            int maxValue = couple[0];
            int maxIndex = 0;
            for (int i = 0; i < couple.Length; i++)
            {
                if (couple[i] > maxValue)
                {
                    maxValue = couple[i];
                    maxIndex = i;
                }
            }
            str[maxIndex] = str[len - maxIndex - 1] = 'a';
        }

        /// <summary>
        /// 不经过交换机，队列点对点
        /// </summary>
        public static void Basic()
        {
            ConnectionFactory connectionFactory = new ConnectionFactory()
            {
                VirtualHost = "xjl_vh",
                UserName = "xjl",
                Password = "xjl",
                HostName = "127.0.0.1"
            };
            using (IConnection conn = connectionFactory.CreateConnection())
            using (IModel channel = conn.CreateModel())
            {
                channel.QueueDeclare(queue: "mymessage", durable: false, exclusive: false, autoDelete: false, arguments: null);

                Console.WriteLine("输入需要传输的消息，输入Exit退出");
                var message = Console.ReadLine();
                while (message != "Exit")
                {
                    var body = Encoding.UTF8.GetBytes(message);
                    channel.BasicPublish(exchange: "", routingKey: "mymessage", basicProperties: null, body: body);
                    Console.WriteLine("发送消息{0}", message);
                    message = Console.ReadLine();
                }
            }
        }
        /// <summary>
        /// 经过交换机，广播模式
        /// </summary>
        public static void Fanout()
        {

            ConnectionFactory connectionFactory = new ConnectionFactory()
            {
                VirtualHost = "xjl_vh",
                UserName = "xjl",
                Password = "xjl",
                HostName = "127.0.0.1"
            };
            using (IConnection conn = connectionFactory.CreateConnection())
            using (IModel channel = conn.CreateModel())
            {
                //channel.QueueDeclare(queue:"mymessage",durable:false, exclusive:false,autoDelete:false,arguments:null);
                channel.ExchangeDeclare(exchange: "xjl_exchange", type: ExchangeType.Fanout, durable: true, autoDelete: false, arguments: null);
                Console.WriteLine("输入需要传输的消息，输入Exit退出");
                var message = Console.ReadLine();
                while (message != "Exit")
                {
                    var body = Encoding.UTF8.GetBytes(message);
                    channel.BasicPublish(exchange: "xjl_exchange", routingKey: "", basicProperties: null, body: body);
                    Console.WriteLine("发送消息{0}", message);
                    message = Console.ReadLine();
                }


            }
        }


        /// <summary>
        /// 经过交换机，直连模式
        /// </summary>
        public static void Direct()
        {

            ConnectionFactory connectionFactory = new ConnectionFactory()
            {
                VirtualHost = "xjl_vh",
                UserName = "xjl",
                Password = "xjl",
                HostName = "127.0.0.1"
            };
            using (IConnection conn = connectionFactory.CreateConnection())
            using (IModel channel = conn.CreateModel())
            {
                //channel.QueueDeclare(queue:"mymessage",durable:false, exclusive:false,autoDelete:false,arguments:null);
                channel.ExchangeDeclare(exchange: "xjl.exchange", type: ExchangeType.Direct, durable: true, autoDelete: false, arguments: null);
                Console.WriteLine("输入需要传输的消息，输入Exit退出");
                var message = Console.ReadLine();
                while (message != "Exit")
                {
                    var body = Encoding.UTF8.GetBytes(message);
                    channel.BasicPublish(exchange: "xjl.exchange", routingKey: "email", basicProperties: null, body: body);
                    Console.WriteLine("发送消息{0}", message);
                    message = Console.ReadLine();
                }


            }
        }




        /// <summary>
        /// 经过交换机，主题模式
        /// </summary>
        public static void Topic()
        {

            ConnectionFactory connectionFactory = new ConnectionFactory()
            {
                VirtualHost = "xjl_vh",
                UserName = "xjl",
                Password = "xjl",
                HostName = "127.0.0.1"
            };
            using (IConnection conn = connectionFactory.CreateConnection())
            using (IModel channel = conn.CreateModel())
            {
                //channel.QueueDeclare(queue:"mymessage",durable:false, exclusive:false,autoDelete:false,arguments:null);
                channel.ExchangeDeclare(exchange: "amq.topic", type: ExchangeType.Topic, durable: true, autoDelete: false, arguments: null);
                Console.WriteLine("输入需要传输的消息，输入Exit退出");
                var message = Console.ReadLine();
                while (message != "Exit")
                {
                    var body = Encoding.UTF8.GetBytes(message);
                    channel.BasicPublish(exchange: "amq.topic", routingKey: "hello.email.message", basicProperties: null, body: body);
                    Console.WriteLine("发送消息{0}", message);
                    message = Console.ReadLine();
                }


            }
        }



        public  static void TestRabbitMQ()
        {
            MQSender mQSender = new MQSender("127.0.0.1", "xjl_vh", "xjl", "xjl", "amq.topic", ExchangeType.Topic);
            MQReceiver mQReceiver = new MQReceiver("127.0.0.1", "xjl_vh", "xjl", "xjl", "amq.topic", ExchangeType.Topic);
            MQReceiver mQReceiver2 = new MQReceiver("127.0.0.1", "xjl_vh", "xjl", "xjl", "amq.topic", ExchangeType.Topic);
            //mQReceiver.Bind("bag", "*.customer", React1);
            //mQReceiver.Bind("bag", "company", React2);
            //mQReceiver2.Bind("bag", "customer", React1);
            mQReceiver2.Bind("complaint", "customer", React1);
            //mQSender.SendMessage(new QueueMessage() { Action = QueueMessage.ActionType.User, Bag = new Bag() { ID=2}, Complaint = new Complaint() }, "company");
            //mQSender.SendMessage(new QueueMessage() { Action = QueueMessage.ActionType.User, Bag = new Bag() { ID = 1 }, Complaint = new Complaint() }, "customer");

            Console.ReadLine();
        }


        public static void React1(QueueMessage message)
        {
            Console.WriteLine("bag customer {0}", message.ToString());
        }
        public static void React2(QueueMessage message)
        {
            Console.WriteLine("bag company {0}", message.ToString());
        }
    }

}




